<?php

namespace app\admin\model;

use app\common\model\Sms;
use app\model\CommonModel;
use think\facade\Db;
use think\model\concern\SoftDelete;

class SmsSendList extends CommonModel
{
    use SoftDelete;
    public function getList($params)
    {
        $where = $this->setWhere($params);
        $paginate = [
            'page' => $params['page'] ?? 1,
            'list_rows' => $params['list_rows'] ?? 10,
        ];
        $attr = ['待发送', '发送成功', '发送失败', '发送中'];
        $list = self::field('id,status,mobile,send_at,result_at')
            ->where($where)
            ->order('id desc')
            ->paginate($paginate)->toArray();
        foreach ($list['data'] as &$nv) {
            $nv['status_text'] = $attr[$nv['status']];
            if (!empty($nv['send_at'])) {
                $nv['send_at'] = date('Y-m-d H:i:s', $nv['send_at']);
            } else {
                $nv['send_at'] = '';
            }
        }

        return success('操作成功', $list);
    }

    //设置条件
    public function setWhere($params)
    {
        $where = [];
        $sms_id = $params['sms_id'] ?? 0;
        $where[] = ['sms_id', '=', $sms_id];
        if (!empty($params['mobile'])) {
            $where[] = ['mobile', 'like', '%' . $params['mobile'] . '%'];
        }
        if (isset($params['status']) && $params['status'] >= 0) {
            $where[] = ['status', '=', $params['status']];
        }

        return $where;
    }

    //获取时间达到还没发送短信的 批量进行发送
    public function sendAllSms()
    {
        $theTime = time();
        $sms = new Sms();
        $list = Db::name("sms_send_list")
            ->alias('a')
            ->field('a.mobile,b.content,a.sms_id,b.send_num,a.send_at')
            ->join('sms_list b', 'a.sms_id = b.id', 'left')
            ->where('b.status', 0)
            ->where('a.status', 0)
            ->whereTime('a.send_at', 'between', [100, $theTime])
            ->select();
        $result = [];
        foreach ($list as $nk => $nv) {
            $result[$nv['sms_id']]['mobile'][] = $nv['mobile'];
            $result[$nv['sms_id']]['content'] = $nv['content'];
            $result[$nv['sms_id']]['send_num'] = $nv['send_num'];
            $result[$nv['sms_id']]['send_at'] = $nv['send_at'];
        }
        foreach ($result as $k => $v) {
            $mobile = implode(',', $v['mobile']);
            $result = $sms->sendSms($mobile, $v['content']);
            if ($result['respCode'] == 0) {
                $saveSend = ['status' => 3];
                $saveList = ['status' => 1, 'sending_num' => $v['send_num']];
                if ($v['send_at'] == 0) {
                    $saveSend['send_at'] = $theTime;
                    $saveList['send_at'] = $theTime;
                }
                Db::name('sms_send_list')->where('sms_id', $k)->update($saveSend);
                Db::name('sms_list')->where('id', $k)->update($saveList);
            } else {
                Db::name('sms_list')->where('id', $k)->update(['status' => 2, 'fail_msg' => $result['respMsg']]);
            }
        }

        return $result;
    }

    //短信结果通知
    public function  smsStatus($params)
    {
        $report = $params['report'] ?? '';
        $reportAttr = explode(',', $report);
        $result = 1;
        if (!empty($reportAttr) && count($reportAttr) == 4) {
            $mobile = $reportAttr[1];
            $status = $reportAttr[2] == 'DELIVRD' ? 1 : 2;
            Db::startTrans();
            try {
                $find = Db::name("sms_send_list")->where('status', 3)->where('mobile', $mobile)->order('id asc')->lock(true)->find();
                $time = date('Y-m-d H:i:s');
                $result = Db::name("sms_send_list")->where('id', $find['id'])->update(['status' => $status, 'result_at' => $time]);
                if ($status == 1) {
                    Db::name('sms_list')->where('id', $find['sms_id'])->inc('success_num')->dec('sending_num')->update();
                } else {
                    Db::name('sms_list')->where('id', $find['sms_id'])->inc('fail_num')->dec('sending_num')->update();
                }
                Db::commit();
            } catch (\Exception $e) {
                Db::rollback();
                return 2;
            }
        }
        return $result;
    }
}
